{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Introducing Julia\n",
    "\n",
    "Julia is a fast, dynamic language designed for numerical and scientific computing. Julia's syntax is superficially similar to Python, MATLAB, and other familiar languages, but its sophisticated compiler is able to produce native code with similar performance to C and FORTRAN.\n",
    "\n",
    "For more information, check out the Julia homepage: <https://julialang.org/>\n",
    "\n",
    "### Julia is...\n",
    "\n",
    "* Fast. Check out the next notebook for some evidence. \n",
    "* Free. That means you are free to do whatever you want with Julia (including developing proprietary tools) forever. \n",
    "* Open-Source: The source code for Julia itself is available at https://github.com/julialang/julia and the source code for all of the packages used in this demo can be found on Github as well. \n",
    "\n",
    "\n",
    "### Julia is *not*...\n",
    "\n",
    "* ROS. Nor is Julia a complete solution for robotics development. It's a programming language that makes it easier to create the tools you need, but it doesn't have all those tools yet. We're working on it! \n",
    "* Object-Oriented. Julia uses *multiple dispatch* to organize functions and behaviors. \n",
    "* Finished. Julia v1.0 is coming summer 2018, but it's not available as of this talk (May 2018). There will be changes between the code you see here and what will be recommended in 1.0. \n",
    "\n",
    "\n",
    "## Getting Julia\n",
    "\n",
    "You can install Julia from <https://julialang.org/downloads/>. This document was designed with Julia v0.6.2 in mind, but should work correctly with any 0.6.x version. \n",
    "\n",
    "## Getting Help\n",
    "\n",
    "For help with this tutorial, you can open a new issue here: <https://github.com/rdeits/DynamicWalking2018.jl/issues>. For general help with Julia usage, try the [Julia forum](https://discourse.julialang.org/) or the [Julia Slack chat group](https://slackinvite.julialang.org/)\n",
    "\n",
    "## Starting Julia\n",
    "\n",
    "On Mac or Windows, just run the \"Julia\" executable. On Linux, you can run the `julia` binary or [add it to your path](https://julialang.org/downloads/platform.html#generic-linux-binaries). At startup, you will see the Julia REPL, where you can run Julia commands: \n",
    "\n",
    "![Julia REPL in terminal](img/julia-repl.png)\n",
    "\n",
    "## Other Julia Environments\n",
    "\n",
    "For a more full-featured Julia environment, check out: \n",
    "\n",
    "### Julia IDEs\n",
    "\n",
    "* Juno: A Julia IDE built on top of Atom: http://junolab.org/\n",
    "* Julia-VSCode: A Julia IDE plugin for the VSCode editor: https://github.com/JuliaEditorSupport/julia-vscode\n",
    "\n",
    "### JuliaPro (not recommended for this tutorial)\n",
    "\n",
    "[JuliaPro](https://juliacomputing.com/products/juliapro.html) is a self-contained commercial Julia environment and IDE (based on Juno). This tutorial *will not* work properly in JuliaPro (as of May 2018) because we need a number of packages not included in that bundle. \n",
    "\n",
    "### Jupyter Support\n",
    "\n",
    "Julia works very well in [Jupyter notebooks](http://jupyter.org/). In fact, this document was created using Julia in a Jupyter notebook. To use Julia with Jupyter, you will need the [IJulia](https://github.com/JuliaLang/IJulia.jl) package. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Using Julia\n",
    "\n",
    "Basic Julia operations will look familiar to those with MATLAB or Python experience:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2 + 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n"
     ]
    }
   ],
   "source": [
    "println(\"hello world\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Arrays\n",
    "\n",
    "Julia has built-in support for arrays with arbitrary element types and arbitrary numbers of dimensions:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3-element Array{Int64,1}:\n",
       " 1\n",
       " 2\n",
       " 3"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Vectors:\n",
    "\n",
    "x = [1, 2, 3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2 Array{Int64,2}:\n",
       " 1  2\n",
       " 3  4"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Matrices:\n",
    "\n",
    "x = [1 2\n",
    "     3 4]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2×2×2 Array{Float64,3}:\n",
       "[:, :, 1] =\n",
       " 1.0  1.0\n",
       " 1.0  1.0\n",
       "\n",
       "[:, :, 2] =\n",
       " 1.0  1.0\n",
       " 1.0  1.0"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# N-dimensional arrays:\n",
    "\n",
    "x = ones(2, 2, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Indexing and slicing arrays is also easy. Julia's Array type uses a 1-based index (like FORTRAN and MATLAB) and stores its entries in column-major order (like FORTRAN and MATLAB). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [1 2\n",
    "     3 4]\n",
    "\n",
    "x[1, 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2-element Array{Int64,1}:\n",
       " 1\n",
       " 3"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[:, 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2-element Array{Int64,1}:\n",
       " 2\n",
       " 4"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[:, end]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Of course, we can do more than just create and index arrays. For example: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Seed the random number generator so that it will\n",
    "# produce the same set of random numbers. \n",
    "#\n",
    "# You don't generally need to do this, but it ensures\n",
    "# that you'll see exactly the same results we do for\n",
    "# this demo. \n",
    "srand(42);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4×4 Array{Float64,2}:\n",
       " 0.533183   0.958926  0.956916  0.422956\n",
       " 0.454029   0.973566  0.584284  0.602298\n",
       " 0.0176868  0.30387   0.937466  0.363458\n",
       " 0.172933   0.176909  0.160006  0.383491"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = rand(4, 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4×4 Array{Float64,2}:\n",
       " 1.53318  1.95893  1.95692  1.42296\n",
       " 1.45403  1.97357  1.58428  1.6023 \n",
       " 1.01769  1.30387  1.93747  1.36346\n",
       " 1.17293  1.17691  1.16001  1.38349"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x .+ 1 # The `.` notation applies a function elementwise:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4×4 Array{Float64,2}:\n",
       " 0.508277   0.818575  0.817419  0.410458\n",
       " 0.43859    0.826896  0.551602  0.566537\n",
       " 0.0176859  0.299215  0.806061  0.355509\n",
       " 0.172072   0.175987  0.159324  0.37416 "
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Unlike in MATLAB, the `.` notation works for *any function*:\n",
    "sin.(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4×4 Array{Float64,2}:\n",
       "  1.0          -1.11022e-15  -1.66533e-15  -8.88178e-16\n",
       "  0.0           1.0           1.11022e-16   0.0        \n",
       " -1.38778e-17   1.73472e-17   1.0          -6.93889e-17\n",
       " -5.55112e-17  -5.55112e-17   0.0           1.0        "
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inv(x) * x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We might expect to see `inv(x) * x` yield exactly the identity, but this doesn't happen due to the rounding issues which are present in all floating-point math (in any language).\n",
    "\n",
    "Fortunately, Julia has excellent support for arrays with arbitrary element types, so let's compute the inverse in exact, rational arithmetic instead: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4×4 Array{Rational{BigInt},2}:\n",
       " 2401242832375411//4503599627370496  …   476206419934121//1125899906842624\n",
       " 2044765445845603//4503599627370496     1356253579026917//2251799813685248\n",
       "     311149946105//17592186044416        818435606833973//2251799813685248\n",
       "  778821124680505//4503599627370496     1727090801564085//4503599627370496"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_rational = Rational{BigInt}.(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4×4 Array{Rational{BigInt},2}:\n",
       " 1//1  0//1  0//1  0//1\n",
       " 0//1  1//1  0//1  0//1\n",
       " 0//1  0//1  1//1  0//1\n",
       " 0//1  0//1  0//1  1//1"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inv(x_rational) * x_rational"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Functions\n",
    "\n",
    "Defining and using a function in Julia is easy: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "say_hello (generic function with 1 method)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "function say_hello(name)\n",
    "    println(\"hello \", name)\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n"
     ]
    }
   ],
   "source": [
    "say_hello(\"world\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "By default, a function is generic, so you can pass in any type you want: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello [1, 2, 3]\n"
     ]
    }
   ],
   "source": [
    "say_hello([1, 2, 3])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "But Julia also allows you express restrictions on a particular method's input types. We can define a function multiple times with different type signatures, and Julia will always pick the most specific signature that matches our inputs: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello number 5\n",
      "hello Float64 5.0\n"
     ]
    }
   ],
   "source": [
    "# a special greeting for numbers\n",
    "function say_hello(x::Number)\n",
    "    println(\"hello number \", x)\n",
    "end\n",
    "\n",
    "# An even more special greeting for floating-point numbers\n",
    "function say_hello(x::Float64)\n",
    "    println(\"hello Float64 \", x)\n",
    "end\n",
    "\n",
    "say_hello(5)   # 5 is an Int, and Int is a kind of Number, so we get the say_hello(x::Number) method\n",
    "say_hello(5.0) # 5.0 is a Float64, and Float64 is more specific than Number, so wet get say_hello(x::Float64)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Julia also has a short one-line syntax for defining simple functions: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "say_goodbye (generic function with 1 method)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "say_goodbye(name) = println(\"goodbye \", name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "goodbye world\n"
     ]
    }
   ],
   "source": [
    "say_goodbye(\"world\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The last expression inside a function is automatically returned as its result (but you can also use the explicit `return` keyword if you prefer). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "function add(x, y)\n",
    "    x + y\n",
    "end\n",
    "\n",
    "# Or, equivalently, we could write:\n",
    "# add(x, y) = x + 1\n",
    "\n",
    "add(1, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Types\n",
    "\n",
    "Julia values have types, and you can create your own types to organize and control your code: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Float64"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "typeof(1.0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Int64"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "typeof(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "UInt8"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "typeof(0x03)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array{Int64,1}"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "typeof([1, 2, 3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3-element Array{Float64,1}:\n",
       " 1.0\n",
       " 2.0\n",
       " 3.0"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "convert(Array{Float64, 1}, [1, 2, 3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Person(\"Alice\", 42)"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "struct Person\n",
    "  name::String\n",
    "  age::Int\n",
    "end\n",
    "\n",
    "alice = Person(\"Alice\", 42)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Julia's types are extremely lightweight, and user-defined types are *exactly* as performant as anything built-in:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sizeof(Person) == sizeof(Ptr{String}) + sizeof(Int)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Packages\n",
    "\n",
    "As of this writing, there are [1,853 registered Julia packages](https://pkg.julialang.org/), and [thousands more available on Github](https://github.com/search?utf8=%E2%9C%93&q=language%3Ajulia&type=). To install a registered package, use `Pkg.add()`: \n",
    "\n",
    "```julia\n",
    "Pkg.add(\"Colors\")\n",
    "```\n",
    "\n",
    "To load an installed package and bring its functions and types into your workspace, you can use `using`: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "using Colors"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\"\n",
       "     width=\"180.0mm\" height=\"25.0mm\"\n",
       "     shape-rendering=\"crispEdges\">\n",
       "<rect x=\"0.0mm\" y=\"0.0mm\"\n",
       "      width=\"17.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#000000\" stroke=\"none\" />\n",
       "<rect x=\"18.0mm\" y=\"0.0mm\"\n",
       "      width=\"17.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#FFFF62\" stroke=\"none\" />\n",
       "<rect x=\"36.0mm\" y=\"0.0mm\"\n",
       "      width=\"17.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#FF9FFF\" stroke=\"none\" />\n",
       "<rect x=\"54.0mm\" y=\"0.0mm\"\n",
       "      width=\"17.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#00D6FF\" stroke=\"none\" />\n",
       "<rect x=\"72.0mm\" y=\"0.0mm\"\n",
       "      width=\"17.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#D74400\" stroke=\"none\" />\n",
       "<rect x=\"90.0mm\" y=\"0.0mm\"\n",
       "      width=\"17.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#008029\" stroke=\"none\" />\n",
       "<rect x=\"108.0mm\" y=\"0.0mm\"\n",
       "      width=\"17.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#005FD5\" stroke=\"none\" />\n",
       "<rect x=\"126.0mm\" y=\"0.0mm\"\n",
       "      width=\"17.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#930068\" stroke=\"none\" />\n",
       "<rect x=\"144.0mm\" y=\"0.0mm\"\n",
       "      width=\"17.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#FFCBB5\" stroke=\"none\" />\n",
       "<rect x=\"162.0mm\" y=\"0.0mm\"\n",
       "      width=\"17.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#A78600\" stroke=\"none\" />\n",
       "</svg>"
      ],
      "text/plain": [
       "10-element Array{ColorTypes.RGB{FixedPointNumbers.Normed{UInt8,8}},1}:\n",
       " RGB{N0f8}(0.0,0.0,0.0)    \n",
       " RGB{N0f8}(1.0,1.0,0.384)  \n",
       " RGB{N0f8}(1.0,0.624,1.0)  \n",
       " RGB{N0f8}(0.0,0.839,1.0)  \n",
       " RGB{N0f8}(0.843,0.267,0.0)\n",
       " RGB{N0f8}(0.0,0.502,0.161)\n",
       " RGB{N0f8}(0.0,0.373,0.835)\n",
       " RGB{N0f8}(0.576,0.0,0.408)\n",
       " RGB{N0f8}(1.0,0.796,0.71) \n",
       " RGB{N0f8}(0.655,0.525,0.0)"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "distinguishable_colors(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\"\n",
       "     width=\"125.0mm\" height=\"125.0mm\"\n",
       "     shape-rendering=\"crispEdges\">\n",
       "<rect x=\"0.0mm\" y=\"0.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#0F3781\" stroke=\"none\" />\n",
       "<rect x=\"25.0mm\" y=\"0.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#166472\" stroke=\"none\" />\n",
       "<rect x=\"50.0mm\" y=\"0.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#B91D72\" stroke=\"none\" />\n",
       "<rect x=\"75.0mm\" y=\"0.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#A06DCD\" stroke=\"none\" />\n",
       "<rect x=\"100.0mm\" y=\"0.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#5D3CD5\" stroke=\"none\" />\n",
       "<rect x=\"0.0mm\" y=\"25.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#0E0DA4\" stroke=\"none\" />\n",
       "<rect x=\"25.0mm\" y=\"25.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#3FE5D7\" stroke=\"none\" />\n",
       "<rect x=\"50.0mm\" y=\"25.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#CBDCDA\" stroke=\"none\" />\n",
       "<rect x=\"75.0mm\" y=\"25.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#A90F22\" stroke=\"none\" />\n",
       "<rect x=\"100.0mm\" y=\"25.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#EF4D4B\" stroke=\"none\" />\n",
       "<rect x=\"0.0mm\" y=\"50.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#46EA72\" stroke=\"none\" />\n",
       "<rect x=\"25.0mm\" y=\"50.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#484338\" stroke=\"none\" />\n",
       "<rect x=\"50.0mm\" y=\"50.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#CFBC6A\" stroke=\"none\" />\n",
       "<rect x=\"75.0mm\" y=\"50.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#D1CD86\" stroke=\"none\" />\n",
       "<rect x=\"100.0mm\" y=\"50.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#4A008C\" stroke=\"none\" />\n",
       "<rect x=\"0.0mm\" y=\"75.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#8658AF\" stroke=\"none\" />\n",
       "<rect x=\"25.0mm\" y=\"75.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#D49FD6\" stroke=\"none\" />\n",
       "<rect x=\"50.0mm\" y=\"75.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#A57698\" stroke=\"none\" />\n",
       "<rect x=\"75.0mm\" y=\"75.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#4A0840\" stroke=\"none\" />\n",
       "<rect x=\"100.0mm\" y=\"75.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#187839\" stroke=\"none\" />\n",
       "<rect x=\"0.0mm\" y=\"100.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#070196\" stroke=\"none\" />\n",
       "<rect x=\"25.0mm\" y=\"100.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#F1A5CD\" stroke=\"none\" />\n",
       "<rect x=\"50.0mm\" y=\"100.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#1C0FB0\" stroke=\"none\" />\n",
       "<rect x=\"75.0mm\" y=\"100.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#6186B8\" stroke=\"none\" />\n",
       "<rect x=\"100.0mm\" y=\"100.0mm\"\n",
       "      width=\"24.0mm\" height=\"24.0mm\"\n",
       "      fill=\"#477C26\" stroke=\"none\" />\n",
       "</svg>"
      ],
      "text/plain": [
       "5×5 Array{ColorTypes.RGB{Float32},2}:\n",
       " RGB{Float32}(0.0598927,0.213935,0.507764)   …  RGB{Float32}(0.364879,0.235901,0.836206)   \n",
       " RGB{Float32}(0.0551811,0.0516672,0.642029)     RGB{Float32}(0.936658,0.300937,0.292358)   \n",
       " RGB{Float32}(0.273129,0.91774,0.446692)        RGB{Float32}(0.288352,0.000409245,0.550858)\n",
       " RGB{Float32}(0.524849,0.345904,0.688028)       RGB{Float32}(0.0954615,0.469825,0.223611)  \n",
       " RGB{Float32}(0.0281593,0.004969,0.588148)      RGB{Float32}(0.278001,0.48513,0.147485)    "
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rand(RGB{Float32}, 5, 5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can install any package from Github (or any other git hosting service) with `Pkg.clone()`: \n",
    "\n",
    "```julia\n",
    "Pkg.clone(\"https://github.com/rdeits/DynamicWalking2018.jl\")\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Julia Plays Well with Others\n",
    "\n",
    "Julia is a great language, but sometimes you need to use an existing tool rather than re-implementing it. Fortunately, it's very easy to call C, FORTRAN, and Python code directly from Julia. \n",
    "\n",
    "## Calling C and FORTRAN from Julia\n",
    "\n",
    "Julia has built-in support for calling C and FORTRAN functions: https://docs.julialang.org/en/stable/manual/calling-c-and-fortran-code/\n",
    "\n",
    "For example, let's get the current CPU time using the C standard library `libc`: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "19551588"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ccall((:clock, \"libc\"), Int32, ())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Julia even knows how to convert certain types like Arrays and Strings to their C equivalents: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ccall((:strcmp, \"libc\"), Cint, (Cstring, Cstring), \"hello\", \"hello\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Calling Python from Julia\n",
    "\n",
    "Python support is provided by the [PyCall.jl](https://github.com/JuliaPy/PyCall.jl) package. To install it, just run: \n",
    "\n",
    "```julia\n",
    "Pkg.add(\"PyCall\")\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "using PyCall"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "@pyimport datetime"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2018-05-24T09:12:48.441"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "datetime.datetime[:today]()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we'll show off Julia's performance compared to C and Python... "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Julia 0.6.2",
   "language": "julia",
   "name": "julia-0.6"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "0.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
